package lib;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import javax.imageio.ImageIO;

import lib.map.objects.MapElement;
import lib.map.objects.MapObjectsList;
import lib.player.items.Item;
import lib.player.items.ItemList;

public class Parser {
	Utils util = new Utils();
	public ItemList items = new ItemList();
	public MapObjectsList mapList = new MapObjectsList();
	private String input;
	public String src;

	public Parser(File fileName) {
		src = fileName.toString();
		String s = "";
		BufferedReader in = null;
		try {
			FileReader infile = new FileReader("maps/" + fileName);
			in = new BufferedReader(infile);
			String out = "";
			while ((s = in.readLine()) != null) {
				out += s.trim();
			}

			out = out.replaceAll(" ", "");
			out.replaceAll("\t", "");
			input = out;// :P
			worker(out);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				in.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public Parser(String mapsrc) {
		input = mapsrc;// :P
		src = "Strig";
		worker(mapsrc);

	}

	private void worker(String s) {
		String[] work = s.split("}");
		for (String st : work) {
			if (st.startsWith("Item{")) {
				parseItem(st.substring(st.indexOf("{") + 1));
			} else if (st.startsWith("Map{")) {
				parseMap(st.substring(st.indexOf("{") + 1));
			}
		}
		if (Config.debug) {
			BufferedImage bufferedImage = new BufferedImage(1000, 100,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D g2d = bufferedImage.createGraphics();
			for (MapElement e : mapList.list) {
				if (e == null)
					break;
				g2d.drawImage(e.getTexture(0), 100 * e.NR, 0, 100, 100, null);
			}
			g2d.dispose();

			try {
				// Save as PNG
				File file = new File("map-" + src + "-"
						+ System.currentTimeMillis() + ".png");
				ImageIO.write(bufferedImage, "png", file);
			} catch (IOException e) {
			}

			System.out.println(this);
		}

	}

	enum MapEle {
		NR, TEXTURES, HIT, KILL, BLOCK, NAME, COLOR, PICKABLE
	}

	private void parseMap(String strings) {
		String[] work = strings.split(";");
		MapElement i = new MapElement();
		MapEle c;
		for (String st : work) {
			String[] temp = st.split("=");
			c = MapEle.valueOf(temp[0].toUpperCase());
			switch (c) {
			case NR:
				i.NR = Integer.parseInt(temp[1]);
				break;
			case NAME:
				i.Name = temp[1];
				break;
			case TEXTURES:
				i.Textures = getTextures(temp[1]);
				break;
			case HIT:
				i.hitpoints = Integer.parseInt(temp[1]);
				break;
			case BLOCK:
				i.Block = Boolean.parseBoolean(temp[1]);
				break;
			case KILL:
				i.kill = Boolean.parseBoolean(temp[1]);
				break;
			case COLOR:
				i.color = getColor(temp[1]);
				break;
			case PICKABLE:
				i.pickable = Boolean.parseBoolean(temp[1]);
			}

		}
		setMap(i);
	}

	enum Items {
		NR, TEXTURES, DAMAGE, WIN, NAME, COLOR
	}

	private void parseItem(String strings) {
		String[] work = strings.split(";");
		Item i = new Item();
		Items c;
		for (String st : work) {
			String[] temp = st.split("=");
			c = Items.valueOf(temp[0].toUpperCase());
			switch (c) {
			case NR:
				i.NR = Integer.parseInt(temp[1]);
				break;
			case NAME:
				i.Name = temp[1];
				break;
			case TEXTURES:
				i.Textures = getTextures(temp[1]);
				break;
			case DAMAGE:
				i.damage = Integer.parseInt(temp[1]);
				break;
			case WIN:
				i.win = Boolean.parseBoolean(temp[1]);
				break;
			case COLOR:
				i.color = getColor(temp[1]);
				break;

			}
		}
		setItem(i);
		setMap(new MapElement(i));
	}

	private void setMap(MapElement mapElement) {
		if (mapList.list[mapElement.NR] != null)
			throw new RuntimeException("Error parsing MapElement Nr.: "
					+ mapElement.NR);
		mapList.list[mapElement.NR] = mapElement;

	}

	private void setItem(Item i) {
		if (items.list[i.NR] != null)
			throw new RuntimeException("Error parsing Item Nr.: " + i.NR);
		items.list[i.NR] = i;
	}

	Image[] getTextures(String s) {
		String[] src;
		src = s.split(",");
		return util.imageLodaer(src);
	}

	private Color getColor(String val) {
		String[] src;
		src = val.split(",");
		if (src.length < 3 || src.length > 4)
			throw new RuntimeException("To few or to many arguments for Color");
		int[] vals = new int[src.length];
		for (int i = 0; i < src.length; i++) {
			vals[i] = Integer.parseInt(src[i]);
		}
		if (src.length == 3)
			return new Color(vals[0], vals[1], vals[2]);
		else
			return new Color(vals[0], vals[1], vals[2], vals[3]);
	}

	public String toString() {
		return input;
	}

	public static void main(String[] args) {
		new Parser(
				"Map{Nr=0;Name=Space;Block=false;}Map{Nr=1;Textures=data/textures/stone/stone.png;Name=Stone;Block=true;Hit=100;Color=150,150,150;}Map{Nr=2;Name=Blackhole;Textures=	data/textures/blackhole/hole1.png,data/textures/blackhole/hole2.png,data/textures/blackhole/hole3.png,data/textures/blackhole/hole4.png;Block=false;Kill=true;Color=0,0,0;}Item{Nr=3;Name=Stabilisator;Textures=data/textures/items/stabi.png;Damage=0;Win=true;Color=170,51,0;}Item{Nr=4;Name=Bohrer;Textures=data/textures/items/bohrer.png;Damage=50;Win=true;Color=204,204,204;}");
	}
}
